package com.czollmann.android.views;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Locale;

import android.content.Context;
import android.util.AttributeSet;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.View;
import android.view.GestureDetector.SimpleOnGestureListener;
import android.widget.LinearLayout;
import android.widget.TextView;

import com.czollmann.android.Constants;
import com.czollmann.android.DateObjectWrapper;
import com.czollmann.android.R;
import com.czollmann.android.StaticMethods;
import com.czollmann.android.utils.DateObjectWrapperUtils;
import com.czollmann.android.utils.LogUtils;

public class HomeView extends CustomScrollView {
  private GestureDetector gestureDetector;
  private static final int SWIPE_MIN_DISTANCE = 5;
  private static final int SWIPE_THRESHOLD_VELOCITY = 300;
  private static final int listLayoutId = 1000001;
  private int activeFeature = 0;
  private int loadPagesOffset = 2;
  private LinearLayout dayHolder = null;
  private List<LinearLayout> contentHolders = new ArrayList<LinearLayout>();
  int viewWidth = 280;
  boolean drawn = false;

  public HomeView(Context context) {
    super(context);
  }

  @SuppressWarnings("unchecked")
  public HomeView(Context context, AttributeSet attributeSet) {
    super(context);
    if (isInEditMode()) {
      DateObjectWrapperUtils.createTestData();
    }
    StaticMethods.setHomeView(this);
    setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
    dayHolder = new LinearLayout(context);
    dayHolder.setOrientation(LinearLayout.HORIZONTAL);
    dayHolder.setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT,
                                                            LayoutParams.MATCH_PARENT));
    addView(dayHolder);
    /* gestures */
    gestureDetector = new GestureDetector(new MyGestureDetector());
    setOnTouchListener(new View.OnTouchListener() {
      @Override
      public boolean onTouch(View v, MotionEvent event) {
        if (gestureDetector.onTouchEvent(event)) {
          return true;
        } else if (event.getAction() == MotionEvent.ACTION_UP
                  || event.getAction() == MotionEvent.ACTION_CANCEL) {
          int scrollX = getScrollX();
          int featureWidth = getMeasuredWidth();
          activeFeature = ((scrollX + (featureWidth / 2)) / featureWidth);
          int scrollTo = activeFeature * featureWidth;
          smoothScrollTo(scrollTo, 0);
          StaticMethods.getHomeView().setCurrentPage(activeFeature);
          return true;
        } else {
          return false;
        }
      }
    });
  }

  @Override
  protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    draw();
  }

  private void draw() {
    if (!drawn) {
      drawn = true;
      LogUtils.infolog("HomeView: draw()");
      List<DateObjectWrapper> dateObjectWrappers = DateObjectWrapperUtils.getDateObjectWrappers();
      if (getMeasuredWidth() != 0) {
        viewWidth = getMeasuredWidth();
      }
      for (DateObjectWrapper dateObjectWrapper : dateObjectWrappers) {
        /* get layout for day */
        LinearLayout featureLayout = (LinearLayout) View.inflate(dayHolder.getContext(),
                                                                 R.layout.part_day,
                                                                 null);
        featureLayout.setLayoutParams(new LayoutParams(viewWidth, LayoutParams.MATCH_PARENT));
        /* headline */
        TextView headlineText = (TextView) featureLayout.findViewById(R.id.headline);
        headlineText.setText(dateObjectWrapper.getDateTime().toString("EEEEEEEEE",
                                                                      Locale.GERMAN)
                  + " " + Constants.dateFormat.print(dateObjectWrapper.getDateTime()));
        Collections.sort(dateObjectWrapper.getObjects());
        LinearLayout contentHolder = (LinearLayout) featureLayout.findViewById(R.id.contentHolder);
        contentHolders.add(contentHolder);
        dayHolder.addView(featureLayout);
      }
      StaticMethods.getHomeView().setCurrentPage(0);
    }
  }

  /**
   * set the current page
   * 
   * @param i
   */
  private void setCurrentPage(int i) {
    StaticMethods.getTimelineView().setActiveFeature(i);
    /* load content */
    loadPages(i);
  }

  /**
   * load the current page
   * 
   * @param i
   */
  private void loadPages(int currentPage) {
    List<Integer> pages = new ArrayList<Integer>();
    pages.add(currentPage);
    int maxPages = DateObjectWrapperUtils.getDateObjectWrappers().size();
    for (int activeOffset = 1; activeOffset <= loadPagesOffset; activeOffset++) {
      if (currentPage - activeOffset > -1) {
        pages.add(currentPage - activeOffset);
      }
      if (currentPage + activeOffset < maxPages + 1) {
        pages.add(currentPage + activeOffset);
      }
    }
    for (int i = 0; i < contentHolders.size(); i++) {
      if (!pages.contains(i)) {
        LinearLayout contentHolder = contentHolders.get(i);
        if (contentHolder != null) {
          ListLayout listLayout = (ListLayout) contentHolder.findViewById(listLayoutId);
          if (listLayout != null) {
            LogUtils.debuglog("removing list from page: " + i);
            contentHolder.removeView(listLayout);
          }
        }
      }
    }
    // System.gc();
    for (Integer page : pages) {
      loadPage(page);
    }
  }

  private void loadPage(Integer page) {
    if (page < DateObjectWrapperUtils.getDateObjectWrappers().size()) {
      DateObjectWrapper dateObjectWrapper = DateObjectWrapperUtils.getDateObjectWrappers()
                                                                  .get(page);
      LinearLayout contentHolder = contentHolders.get(page);
      if (dateObjectWrapper != null
                && contentHolder.findViewWithTag(dateObjectWrapper) == null) {
        if (contentHolder != null) {
          /* listview */
          LogUtils.debuglog("rendering page: " + page);
          ListLayout listLayout = new ListLayout(this.getContext(),
                                                 dateObjectWrapper.getObjects());
          listLayout.setId(listLayoutId);
          listLayout.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT,
                                                      LayoutParams.WRAP_CONTENT));
          listLayout.setTag(dateObjectWrapper);
          contentHolder.addView(listLayout);
        }
      }
    }
  }

  public void doScroll(int i) {
    activeFeature = i;
    setCurrentPage(i);
    smoothScrollTo((i * getMeasuredWidth()), 0);
  }

  class MyGestureDetector extends SimpleOnGestureListener {
    @Override
    public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
      // TODO Auto-generated method stub
      return super.onScroll(e1, e2, distanceX, distanceY);
    }
    //
    // @Override
    // public boolean onFling(MotionEvent e1, MotionEvent e2, float
    // velocityX, float
    // velocityY) {
    // try {
    // if (e1.getX() - e2.getX() > SWIPE_MIN_DISTANCE
    // && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) {
    // activeFeature = (activeFeature <
    // (DateObjectWrapperUtils.getDateObjectWrappers()
    // .size() - 1))
    // ? activeFeature + 1
    // : DateObjectWrapperUtils.getDateObjectWrappers().size() - 1;
    // smoothScrollTo(activeFeature * getMeasuredWidth(), 0);
    // return true;
    // }
    // // left to right
    // else if (e2.getX() - e1.getX() > SWIPE_MIN_DISTANCE
    // && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) {
    // activeFeature = (activeFeature > 0) ? activeFeature - 1 : 0;
    // smoothScrollTo(activeFeature * getMeasuredWidth(), 0);
    // return true;
    // }
    // }
    // catch (Exception e) {
    // // nothing
    // }
    // return false;
    // }
  }
}
